package com.modelo.dao.documento;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import org.hibernate.FetchMode;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Repository;

import com.comun.filtro.FiltroLista;
import com.modelo.dao.comun.CriteriaFetchMode;
import com.modelo.dao.comun.FiltroBaseDAO;
import com.modelo.dao.comun.HibernateBaseDAO;
import com.modelo.dao.utils.ConstantesDAO;
import com.modelo.dao.utils.UtilsDAO;
import com.modelo.entity.Documento;

@Repository
public class DocumentoDAO extends HibernateBaseDAO<Documento> implements IDocumentoDAO,
		Serializable {

	public static final String CADUCIDAD = "caducidad";

	public static final String DESCRIPCION = "descripcion";
	public static final String ES_COMUN_OBRAS = "esComunObras";

	private static final Logger log = LoggerFactory.getLogger(DocumentoDAO.class);
	public static final String NOMBRE = "nombre";
	private static final long serialVersionUID = 1L;

	public static DocumentoDAO getFromApplicationContext(ApplicationContext ctx) {

		return (DocumentoDAO) ctx.getBean("DocumentoDAO");
	}

	/**
	 * Constructor con el sessionFactory como parametro.
	 * 
	 * @param sessionFactory
	 */
	@Autowired
	public DocumentoDAO(SessionFactory sessionFactory) {
		super(sessionFactory);

	}

	public List<Documento> findByCaducidad(Object caducidad) {
		return findByProperty(CADUCIDAD, caducidad);
	}

	public List<Documento> findByDescripcion(Object descripcion) {
		return findByProperty(DESCRIPCION, descripcion);
	}

	public List<Documento> findByEsComunObras(Object esComunObras) {
		return findByProperty(ES_COMUN_OBRAS, esComunObras);
	}

	public List<Documento> findByNombre(Object nombre) {
		return findByProperty(NOMBRE, nombre);
	}

	@Override
	public List<Documento> findByProperty(String propertyName, Object value) {
		log.debug("finding Documento instance with property: " + propertyName + ", value: " + value);
		try {
			String queryString = "from Documento as model where model." + propertyName + "= ?";
			return getHibernateTemplate().find(queryString, value);
		} catch (RuntimeException re) {
			log.error("find by property name failed", re);
			throw re;
		}
	}

	@Override
	public List<Documento> getDocumentosActivos(FiltroLista filtro) {
		CriteriaFetchMode criteriaFetchMode = new CriteriaFetchMode(FetchMode.JOIN,
				ConstantesDAO.DOCUMENTOS_TIPOS);
		List<CriteriaFetchMode> fetchModes = new ArrayList<CriteriaFetchMode>();
		fetchModes.add(criteriaFetchMode);
		FiltroBaseDAO filtroDAO = new FiltroBaseDAO();
		filtroDAO.setFetchModes(fetchModes);

		return getActivos(filtro, filtroDAO, Documento.class);
	}

	@Override
	public List<Documento> getDocumentosActivosAExcepcion(List<Documento> listaDoc) {
		CriteriaFetchMode criteriaFetchMode = new CriteriaFetchMode(FetchMode.JOIN,
				ConstantesDAO.DOCUMENTOS_TIPOS);
		List<CriteriaFetchMode> fetchModes = new ArrayList<CriteriaFetchMode>();
		fetchModes.add(criteriaFetchMode);
		FiltroBaseDAO filtroDAO = new FiltroBaseDAO();
		filtroDAO.setFetchModes(fetchModes);
		UtilsDAO<Documento> utilsDAO = new UtilsDAO<Documento>();

		if (listaDoc != null && !listaDoc.isEmpty()) {
			Criterion cr = Restrictions.not(Restrictions.in("id",
					utilsDAO.reflectionEntityToListId(listaDoc)));

			List<Criterion> listaCriterions = new ArrayList<Criterion>();
			listaCriterions.add(cr);
			filtroDAO.setListaCriterions(listaCriterions);
		}

		return getActivos(null, filtroDAO, Documento.class);
	}

}